home *** CD-ROM | disk | FTP | other *** search
-
- ;
- ; Nifty James' FREE RAM program
- ; Version 1.13 of 7 May 1987
- ;
- ; Copyright 1987 by Mike Blaszczak, all Rights Reserved.
- ;
- ; Shareware $7
- ;
-
- ; ASCII Characters
-
- tab equ 9
- lf equ 10
- cr equ 13
- space equ 32
-
- ; IBM Specific Keyboard Scan-codes
-
- AltDown equ 56 ; ALT scancode
- AltUp equ 56 + 80h
- RShiftDown equ 54 ; right-shift scancode
- RShiftUp equ 54 + 80h
-
- ; BIOS Interrupts
-
- Timer equ 008h ; BIOS 18.2Hz function
- Keyboard equ 009h ; BIOS keypress call
- Video equ 010h ; BIOS video function
- DiskService equ 013h ; BIOS/XT BIOS disk service
- TickTock equ 01Ch ; the BIOS timer trap
- SnagDOS equ 028h ; a function to snag DOS by
- SigVec equ 0D0h ; vector to point to our signature
-
- ; I/O Ports
-
- NMIPort equ 020h ; the Interrupt controller port
- KeyPort equ 060h ; the keyboard's I/O port
-
- ; DOS Calls
-
- SetVec equ 025h ; call to set an int vector
- KEEP equ 031h ; call to Terminate and Stay Res
- Critical equ 034h ; call to get the DOS critical flag
- GetVec equ 035h ; call to get an int vector
- Allocate equ 048h ; call to allocate memory
- Terminate equ 04Ch ; call to Terminate
-
-
- ; Public declarations for SYMDEB
-
- PUBLIC First
- PUBLIC StackArea, StackTop, SaveAX, SaveSS, SaveSP, ClockVec, ClockVecO
- PUBLIC ClockVecS, Display, DisplayOff, DisplaySeg, DisplayPort, CriticalFlag
- PUBLIC CriticalFlagO, CriticalFlagS, OTT, OTTO, OTTS, OKeyVec, OKeyVecO
- PUBLIC OKeyVecS, OSnagger, OSnaggerO, OSnaggerS, ODiskCall, ODiskCallO
- PUBLIC ODiskCallS, WorkFlag, UpdateFlag, AltFlag, ShiftFlag, Ticks, InDisk
- PUBLIC InThere, DiskTrap, TCTrap, TCDone, TimeTrap, NotTime, KeyTrap
- PUBLIC TryUpAlt, TryDnShift, TryUpShift, TripOut, KeyOut, Signature, WorkTrap
- PUBLIC WorkHard, NoWork, DoWork, CalcLoop, Convert2, Convert3, IsMono
- PUBLIC SynchLow, SynchHigh, PutUp, GetOut, CalcArea, AnswerArea, DebugPlace
- PUBLIC OverResident, Already, Exit, InstallMe, NotMono, Banner
- PUBLIC Installed, Failed
-
-
- CSeg segment para public 'CODE'
- assume ds:CSeg,ss:CSeg,cs:CSeg
-
- org 100h
-
- extrn Show:near ; from NJLIB
-
- First: jmp OverResident
- nop
-
- StackArea dw 199 dup(0DEADh) ; the stack for interrupts
- StackTop dw 0DEADh
-
- Signature db 'NJ' ; the signature
-
- SaveAX dw 0 ; save the AX here
- SaveSS dw 0 ; save the SS and SP here
- SaveSP dw 0
-
-
- ClockVec label dword ; the original clock tick vector
- ClockVecO dw 0
- ClockVecS dw 0
-
- Display label dword ; pointer to display storage
- DisplayOff dw 62*2
- DisplaySeg dw 0B800h ; assume the color card
- DisplayPort dw 03DAh ; display status port address
-
- CriticalFlag label dword ; the DOS critical flag
- CriticalFlagO dw 0
- CriticalFlagS dw 0
-
- OTT label dword ; the original BIOS Timer Trap
- OTTO dw 0
- OTTS dw 0
-
- OKeyVec label dword ; the original keypress vector
- OKeyVecO dw 0
- OKeyVecS dw 0
-
- OSnagger label dword ; the original DOS int 28h
- OSnaggerO dw 0
- OSnaggerS dw 0
-
- ODiskCall label dword ; the disk services place
- ODiskCallO dw 0
- ODiskCallS dw 0
-
- WorkFlag dw 0 ; semaphore; 1 if we should display
- UpdateFlag dw 0 ; semaphore; 1 if we should update
-
- AltFlag db 0 ; set if ALT is pressed
- ShiftFlag db 0 ; set if RShift is pressed
-
- Ticks db 0 ; tick count for timer
- InDisk db 0 ; semaphore; 1 if in disk control
-
- InThere db 0 ; recursiveness flag
-
- ; ---------------------------------------------------------------------------
-
- DiskTrap: inc CS:InDisk ; set disk handler flag
- pushf
- call CS:[ODiskCall] ; call the disk handler
- pushf
- dec CS:InDisk ; reset disk handler flag
- popf
- iret ; return!
-
- ; ---------------------------------------------------------------------------
-
- TCTrap: pushf
- call CS:[OTT] ; call the original
- pushf
- cli
- cmp CS:[WorkFlag],0
- je TCDone
- push es
- push bx ; check the critical flag
- les bx,CS:[CriticalFlag]
- cmp byte ptr es:[bx],0
- pop bx
- pop es
- jne TCDone
-
- cmp CS:[InDisk],0 ; and the disk service flag
- jne TCDone
-
- jmp WorkHard
-
- TCDone: popf
- iret
-
- ; ---------------------------------------------------------------------------
-
- TimeTrap: pushf ; save flags
- push ax
-
- inc CS:Ticks ; increment ticks count
- mov al,CS:Ticks ; is it time?
- cmp al,18
- jne NotTime ; no, not yet
-
- xor ax,ax ; yes, zero time count
- mov CS:Ticks,al
- mov CS:UpdateFlag,1 ; set update flag
-
- NotTime: pop ax
- popf
- jmp CS:[ClockVec]
-
- ; ---------------------------------------------------------------------------
-
- KeyTrap: pushf
- push ax
-
- in al,KeyPort ; get key from keyboard
- cmp al,AltDown ; was ALT pressed?
- jne TryUpAlt ; no. Maybe it was released?
-
- mov CS:AltFlag,1 ; yeah! It was pressed, set flag
- jmp short TripOut ; and flow through
-
- TryUpAlt: cmp al,AltUp ; was ALT released?
- jne TryDnShift ; no, maybe it was shift?
-
- mov CS:AltFlag,0 ; yeah! ALT was released
- jmp short TripOut ; reset flag and go through
-
- TryDnShift: cmp al,RShiftDown ; okay. Maybe RShifty was pressed?
- jne TryUpShift ; nah, maybe it was released?
-
- mov CS:ShiftFlag,1 ; yeah! it was pressed, so set flag
- jmp short TripOut ; and jump through
-
- TryUpShift: cmp al,RShiftUp ; well, maybe it was released?
- jne KeyOut ; no, guess not, just pass it thru
-
- mov CS:ShiftFlag,0 ; yeah, it was released!
-
- TripOut: mov al,CS:AltFlag ; so, is it both ALT and RSHIFT?
- and al,CS:ShiftFlag
- je KeyOut ; no, just pass thru
- not CS:WorkFlag ; yeah, it was! toggle work flag
-
- KeyOut: pop ax
- popf
-
- jmp CS:[OKeyVec]
-
- ; ---------------------------------------------------------------------------
-
-
- WorkTrap: pushf ; simulate a INT
- call CS:[OSnagger]
- pushf
-
- WorkHard: cmp CS:[WorkFlag],0 ; are we activated?
- je NoWork ; no, don't do work
-
- cmp CS:[UpdateFlag],0 ; is it time to update?
- je NoWork ; no, don't do work
-
- cmp CS:[InThere],0 ; are we getting recursive?
- jne NoWork ; yes, don't do work
-
- call DoWork
- NoWork: popf
- iret
-
-
- DoWork: cli ; turn off interrupts!
- cld ; and set direction up!!!
- mov CS:SaveAX,ax ; save the stack seg from call
- mov CS:SaveSP,sp
- mov CS:SaveSS,ss
-
- mov ax,cs ; point to our local
- mov ss,ax ; stack segment
- mov ax,offset StackTop
- mov sp,ax
-
- push bx ; save all the regs we use
- push cx
- push dx
- push si
- push di
- push ds
- push es
-
- mov ax,cs
- mov ds,ax ; establish data seg addressing
- mov es,ax
-
- inc InThere ; don't be recursive
- mov UpDateFlag,0 ; and don't do the work twice!
-
- cli ; reallow interrupts for now
-
- mov ah,Allocate ; try to get a major amount of mem
- mov bx,0FFFFh
- int 21h ; to see how much is free
-
- xor ax,ax ; zero the AX
- xchg ax,bx ; now, AX = paragraphs and BX = 0
- mov cx,4 ; get # of bytes
- CalcLoop: rcl ax,1 ; multiply by two
- rcl bx,1 ; add in carry
- loop CalcLoop
-
- ; now, BX:AX contains bytes of free memory
-
- mov CalcArea,ax ; store bytes
- mov CalcArea+2,bx
-
- mov di,offset AnswerArea
- mov al,space
- mov cx,7
- repnz stosb
-
- ; now, convert the number of bytes into ASCII, and store at
- ; AnswerArea
-
- mov si,offset CalcArea
- dec di
-
- Convert2: push si ; save source pointer
-
- xor bx,bx ; done flag
- mov cx,2 ; 2 words in number
- xor dx,dx ; previous remainder
- add si,2 ; point to high end
-
- Convert3: push cx ; save count
- mov ax,[si] ; get 16-bit digit
- mov cx,10 ; divisor of 10
- div cx ; divide
- mov [si],ax ; put 16-bit digit back
- or bx,ax ; check for zero
- sub si,2 ; point to next 16-bit digit
- pop cx ; restore count
- loop Convert3 ; do more
-
- or dl,'0' ; make remainder into decimal digit
- mov [di],dl ; store it
- dec di ; and fix pointer
-
- pop si ; restore source pointer
- cmp bx,0 ; was that the end?
- jnz Convert2 ; no, do more!
-
- mov ah,15
- int Video
- mov cx,0B000h
- cmp al,7
- je IsMono
- mov cx,0B800h
- add ch,bh ; add the current page to it
-
- IsMono: mov DisplaySeg,cx
-
- les di,Display ; stuff it into the display!
- mov si,offset AnswerArea
- mov ah,7 ; attribute
- mov cx,18 ; 17 characters in the message:
- ; "xxxxxxx Bytes Free"
-
- mov dx,DisplayPort ; get the status port number
- and dx,dx ; or is it mono?
- je PutUp ; yeah, skip synchro
-
- SynchLow: ; wait for the synch to go low
- in al,dx
- test al,8
- jne SynchLow
-
- SynchHigh: ; wait for start of overscan
- in al,dx
- test al,8
- je SynchHigh
-
- PutUp: lodsb ; load a byte of the message
- stosw ; store a word into the display
- loop PutUp ; do the rest
-
- GetOut: cli ; disallow interrupts for crucial code
- dec InThere ; clear work flag
- pop es
- pop ds ; reset the registers
- pop di
- pop si
- pop dx
- pop cx
- pop bx
-
- mov sp,CS:SaveSP ; restore the original stack
- mov ss,CS:SaveSS
- mov ax,CS:SaveAX
-
- sti ; re-allow ints and
- ret ; return to caller
-
- CalcArea dw 2 dup(0)
-
- AnswerArea db 7 dup (' ')
- DebugPlace db " Bytes Free"
-
- ; ---------------------------------------------------------------------------
-
- OverResident: mov dx,offset Banner ; print the banner
- mov cx,BannerLen
- call Show
-
- mov ah,GetVec ; see if already present
- mov al,SigVec
- int 21h
-
- mov ax,ES:[BX] ; see if the signature
- cmp ax,'JN' ; is there?
- jne InstallMe
-
- Already: mov dx,offset Failed ; already installed!
- mov cx,FailedLen
- call Show
-
- Exit: mov ah,Terminate ; terminate with ERRORLEVEL
- mov al,1
- int 21h
-
- InstallMe: mov ah,Critical ; get the DOS critical flag
- int 21h
- mov CriticalFlagO,bx
- mov CriticalFlagS,es
-
- mov ah,GetVec ; handle the tick-tock
- mov al,TickTock
- int 21h
- mov OTTO,bx
- mov OTTS,es
-
- mov ah,SetVec
- mov al,TickTock
- mov dx,offset TCTrap
- int 21h
-
- mov ah,GetVec
- mov al,DiskService
- int 21h
- mov ODiskCallO,bx
- mov ODiskCallS,es
-
- mov ah,GetVec
- mov al,SnagDOS ; get originial INT 028h
- int 21h
- mov OSnaggerO,bx
- mov OSnaggerS,es
-
- mov ah,GetVec ; get the current keyboard vec
- mov al,Keyboard
- int 21h
-
- mov OKeyVecO,bx
- mov OKeyVecS,es
-
- mov ah,GetVec ; get the clock-tick vec
- mov al,Timer
- int 21h
-
- mov ClockVecO,bx ; store clock vector
- mov ax,es
- mov ClockVecS,ax
-
- mov ah,15 ; call BIOS to get video mode
- int Video
- cmp al,7 ; is it mono?
- jne NotMono
-
- mov ax,0B000h ; yes, change it to mono
- mov DisplaySeg,ax
- mov ax,0
- mov DisplayPort,ax
-
- NotMono: mov ah,SetVec ; set an int vector
- mov al,Timer ; the timer's
- mov dx,offset TimeTrap ; to our routine
- int 21h
-
- mov ah,SetVec ; get the keypress vector
- mov al,Keyboard
- mov dx,offset KeyTrap
- int 21h
-
- mov ah,SetVec ; get the snag DOS vector
- mov al,SnagDOS
- mov dx,offset WorkTrap
- int 21h
-
- mov ah,SetVec ; set the signature pointer
- mov al,SigVec
- mov dx,offset Signature
- int 21h
-
- mov dx,offset Installed
- mov cx,InstalledLen
- call Show
-
- mov ah,KEEP ; terminate and stay resident
- mov al,0
- mov dx,offset OverResident
- add dx,15
- mov cx,4
- shr dx,cl
- int 21h
-
- ; ---------------------------------------------------------------------------
-
- Banner db cr,lf,"Nifty James' FREE RAM program",cr,lf
- db "Version 1.13 of 07 May 1987",cr,lf,lf
- BannerLen equ this byte - Banner
-
- Installed db cr,lf,"NJFRERAM is installed!",cr,lf
- db "Press <Alt>+<RightShift> to toggle the display",cr,lf,lf
- InstalledLen equ this byte - Installed
-
- Failed db cr,lf,"NJFRERAM was already present!",cr,lf,lf
- FailedLen equ this byte - Failed
-
- CSeg ends
- end First
-
-